﻿// ===============================================================================
// 西交投Windows窗体应用程序开发平台 版权所有
// ===============================================================================

using System;
using System.Collections.Generic;

namespace XCI.Extensions
{
    public static class ListExtensions
    {
        /// <summary>
        /// 元素上移
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="list">集合</param>
        /// <param name="currentIndex">当前待移动索引</param>
        /// <returns>上移成功返回true,否则返回false</returns>
        public static bool MoveUp<T>(this IList<T> list, int currentIndex)
        {
            if (currentIndex <= 0 || currentIndex >= list.Count - 1) return false;

            var targetIndex = currentIndex - 1;
            return MoveCore(list, currentIndex, targetIndex);
        }

        /// <summary>
        /// 元素下移
        /// </summary>
        /// <typeparam name="T">元素类型</typeparam>
        /// <param name="list">集合</param>
        /// <param name="currentIndex">当前待移动索引</param>
        /// <returns>下移成功返回true,否则返回false</returns>
        public static bool MoveDown<T>(this IList<T> list, int currentIndex)
        {
            if (currentIndex < 0 || currentIndex >= list.Count - 1) return false;

            var targetIndex = currentIndex - 1;
            return MoveCore(list, currentIndex, targetIndex);
        }

        public static bool MoveCore<T>(this IList<T> list, int currentIndex, int targetIndex)
        {
            var current = list[currentIndex];
            list.RemoveAt(currentIndex);
            list.Insert(targetIndex, current);
            return true;
        }

        public static int IndexOfIf<T>(this IList<T> list, Func<T, bool> predicate)
        {
            for (int index = 0; index < list.Count; ++index)
            {
                if (predicate(list[index]))
                    return index;
            }
            return -1;
        }

        public static bool IsValidIndex<T>(this IList<T> array, int index)
        {
            if (array != null && index >= 0)
                return index < array.Count;
            return false;
        }

        public static int GetValidIndex<T>(this IList<T> array, int index)
        {
            return Math.Max(0, Math.Min(index, array.Count - 1));
        }

        public static bool TryGetValue<T>(this IList<T> array, int index, out T value)
        {
            if (array.IsValidIndex<T>(index))
            {
                value = array[index];
                return true;
            }
            value = default(T);
            return false;
        }

        public static T AddOrReplace<T>(this IList<T> @this, Func<T, bool> predicate, T newObj)
        {
            int index = @this.IndexOfIf<T>(predicate);
            if (index != -1)
            {
                @this.RemoveAt(index);
                @this.Insert(index, newObj);
            }
            else
                @this.Add(newObj);
            return newObj;
        }

        public static void RemoveIf<T>(this IList<T> @this, Func<T, bool> predicate)
        {
            for (int index = @this.Count - 1; index >= 0; index--)
            {
                if (predicate(@this[index]))
                    @this.RemoveAt(index);
            }
        }

        /// <summary>
        /// 确定某元素是否在列表中。
        /// </summary>
        /// <param name="list">列表对象</param>
        /// <param name="predicate">查找条件。</param>
        /// <exception cref="System.ArgumentNullException">predicate 为null。</exception>
        /// <returns>如果在列表中找到项，则为true，否则为false。</returns>
        public static bool ContainsIf<TSource>(this IList<TSource> list, Func<TSource, bool> predicate)
        {
            foreach (var item in list)
            {
                if (predicate(item))
                {
                    return true;
                }
            }
            return false;
        }
    }
}